package com.xyzwps.server.paimon.ui

import com.xyzwps.server.paimon.error.AppException
import graphql.GraphQLError
import graphql.GraphqlErrorBuilder
import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandler
import org.springframework.graphql.execution.ErrorType
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ControllerAdvice
import org.slf4j.LoggerFactory

@ControllerAdvice
class GraphQlExceptionHandlers {
    private val log = LoggerFactory.getLogger(GraphQlExceptionHandlers::class.java)

    @GraphQlExceptionHandler
    fun handle(errorBuilder: GraphqlErrorBuilder<*>, ex: Exception): GraphQLError {
        log.error("GraphQlExceptionHandler", ex)

        return when (ex) {
            is AppException -> handle(errorBuilder, ex)
            else -> fallback(errorBuilder, ex)
        }
    }

    private fun handle(errorBuilder: GraphqlErrorBuilder<*>, e: AppException): GraphQLError {
        return errorBuilder
            .errorType(e.errorType)
            .message(e.message) // TODO: i18n
            .extensions(
                mapOf(
                    "type" to "/errors/${e.code}",
                    "status" to e.status.value(),
                    "title" to e.status.name
                )
            )
            .build()
    }

    private fun fallback(errorBuilder: GraphqlErrorBuilder<*>, ex: Exception): GraphQLError {
        return errorBuilder
            .errorType(ErrorType.INTERNAL_ERROR)
            .message(ex.message)
            .extensions(
                mapOf(
                    "title" to ex.javaClass.canonicalName,
                    "status" to HttpStatus.INTERNAL_SERVER_ERROR.name
                )
            )
            .build()
    }
}
